import { inject, computed, h } from 'vue'
import { Option, Value } from './interface'

import { MenuContextKey } from './Menu'
import MenuItem from './MenuItem'
import MenuItemGroup from './MenuItemGroup'
import Submenu, { SubmenuContextKey } from './Submenu'

export function useMenu(props: { disabled: boolean; value: Value }) {
  const menuContext = inject(MenuContextKey, undefined)
  const submenuContext = inject(SubmenuContextKey, undefined)

  const { props: menuProps } = menuContext

  const isRoot = menuContext && !submenuContext

  const horizontalRef = computed(() => {
    return menuProps.mode === 'horizontal'
  })

  const inlineRef = computed(() => {
    return menuProps.mode === 'inline'
  })

  const indentRef = computed(() => {
    return horizontalRef.value ? 0 : menuProps.indent
  })

  const parentPaddingLeftRef = computed(() => {
    if (menuContext.collapsedRef.value) return 0
    if (isRoot) return 0
    if (submenuContext) {
      return submenuContext.paddingLeftRef.value
    }
  })

  const paddingLeftRef = computed<number>(() => {
    if (horizontalRef.value) return undefined
    if (!inlineRef.value) return undefined
    return parentPaddingLeftRef.value + indentRef.value
  })

  const disabledRef = computed<boolean>(() => {
    return menuContext.props.disabled || submenuContext?.props.disabled || props.disabled
  })

  const isActiveRef = computed<boolean>(() => {
    return menuContext.activePathRef.value.includes(props.value)
  })

  return {
    menuContext,
    submenuContext,
    horizontalRef,
    inlineRef,
    indentRef,
    parentPaddingLeftRef,
    paddingLeftRef,
    disabledRef,
    isActiveRef,
    isRoot
  }
}

export function createItem(node: Option) {
  if (node.children) {
    if (node.type === 'group') {
      return h(MenuItemGroup, node)
    } else {
      return h(Submenu, node)
    }
  } else {
    return h(MenuItem, node)
  }
}

// ========================== Tree ==========================
export function traverseTree(tree: Option[], cb: (opt: Option) => void) {
  tree?.forEach(opt => {
    if (opt.children) traverseTree(opt.children, cb)
    cb(opt)
  })
}
export function getNonLeafKeys(tree: Option[]) {
  const keys = [] as Value[]
  traverseTree(tree, opt => keys.push(opt.value))
  return keys
}
export function treeFindPath(tree: Option[], func: (opt: Option) => boolean, path = [] as Value[]): Value[] {
  for (const item of tree) {
    path.push(item.value)
    if (func(item)) return path
    if (item.children) {
      const ret = treeFindPath(item.children, func, path)
      if (ret.length) return ret
    }
    path.pop()
  }
  return []
}
